<template>
  <transition-group class="list">
    <ul
      @dragstart="dragstart(index)"
      @dragenter="dragenter($event, index)"
      @dragover="dragover($event, index)"
      draggable="true"
      v-for="(item, index) in list"
      :key="item.label"
      class="list-item"
    >
      {{ item.label }}
    </ul>
  </transition-group>
</template>

<script>
export default {
  data() {
    return {
      list: [
        { label: '列表1' },
        { label: '列表2' },
        { label: '列表3' },
        { label: '列表4' },
        { label: '列表5' },
        { label: '列表6' },
      ],
      // 源对象的下标
      dragIndex: '',
      // 目标对象的下标
      enterIndex: '',
      timeout: null,
    }
  },
  destroyed() {
    // 每次离开当前界面时，清除定时器
    clearInterval(this.timeout)
    this.timeout = null
  },
  methods: {
    dragstart(index) {
      console.log('start index ===>>> ', index)
      this.dragIndex = index
    },

    // dragenter 和 dragover 事件的默认行为是拒绝接受任何被拖放的元素。
    // 因此，我们要在这两个拖放事件中使用`preventDefault`来阻止浏览器的默认行为
    dragenter(e, index) {
      e.preventDefault()
      this.enterIndex = index
      if (this.timeout !== null) {
        clearTimeout(this.timeout)
      }
      // 拖拽事件的防抖
      this.timeout = setTimeout(() => {
        if (this.dragIndex !== index) {
          const source = this.list[this.dragIndex]
          this.list.splice(this.dragIndex, 1)
          this.list.splice(index, 0, source)
          // 排序变化后目标对象的索引变成源对象的索引
          this.dragIndex = index
        }
      }, 100)
    },
    dragover(e, index) {
      e.preventDefault()
    },
  },
}
</script>

<style lang="scss" scoped>
.list {
  list-style: none;
  .list-item {
    // 设置 动画效果
    transition: transform 0.3s;
    cursor: move;
    width: 300px;
    background: #ea6e59;
    border-radius: 4px;
    color: #fff;
    margin-bottom: 6px;
    height: 50px;
    line-height: 50px;
    text-align: center;
  }
}
</style>
